"""
核心数据模型定义
"""
from dataclasses import dataclass, field
from datetime import datetime
from typing import List, Optional, Dict, Any
from uuid import uuid4

from shared.enums import (
    ComplexityLevel, QuestionCategory, TaskType, ExecutionStatus,
    TaskStatus, AICapability, ExecutionPath, SessionStatus
)


@dataclass
class Question:
    """问题数据模型"""
    id: str = field(default_factory=lambda: str(uuid4()))
    content: str = ""
    complexity: ComplexityLevel = ComplexityLevel.SIMPLE
    category: QuestionCategory = QuestionCategory.FACTUAL
    timestamp: datetime = field(default_factory=datetime.now)
    user_id: Optional[str] = None
    metadata: Dict[str, Any] = field(default_factory=dict)

    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            'id': self.id,
            'content': self.content,
            'complexity': self.complexity.value,
            'category': self.category.value,
            'timestamp': self.timestamp.isoformat(),
            'user_id': self.user_id,
            'metadata': self.metadata
        }

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'Question':
        """从字典创建实例"""
        return cls(
            id=data.get('id', str(uuid4())),
            content=data.get('content', ''),
            complexity=ComplexityLevel(data.get('complexity', 'simple')),
            category=QuestionCategory(data.get('category', 'factual')),
            timestamp=datetime.fromisoformat(data.get('timestamp', datetime.now().isoformat())),
            user_id=data.get('user_id'),
            metadata=data.get('metadata', {})
        )


@dataclass
class Task:
    """任务数据模型"""
    id: str = field(default_factory=lambda: str(uuid4()))
    description: str = ""
    type: TaskType = TaskType.RESEARCH
    dependencies: List[str] = field(default_factory=list)
    estimated_duration: int = 30  # 预估时间（秒）
    required_capabilities: List[AICapability] = field(default_factory=list)
    priority: int = 1  # 优先级，数字越小优先级越高
    status: TaskStatus = TaskStatus.PENDING
    result: Optional[str] = None
    error: Optional[str] = None
    start_time: Optional[datetime] = None
    end_time: Optional[datetime] = None
    metadata: Dict[str, Any] = field(default_factory=dict)

    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            'id': self.id,
            'description': self.description,
            'type': self.type.value,
            'dependencies': self.dependencies,
            'estimated_duration': self.estimated_duration,
            'required_capabilities': [cap.value for cap in self.required_capabilities],
            'priority': self.priority,
            'status': self.status.value,
            'result': self.result,
            'error': self.error,
            'start_time': self.start_time.isoformat() if self.start_time else None,
            'end_time': self.end_time.isoformat() if self.end_time else None,
            'metadata': self.metadata
        }

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'Task':
        """从字典创建实例"""
        return cls(
            id=data.get('id', str(uuid4())),
            description=data.get('description', ''),
            type=TaskType(data.get('type', 'research')),
            dependencies=data.get('dependencies', []),
            estimated_duration=data.get('estimated_duration', 30),
            required_capabilities=[AICapability(cap) for cap in data.get('required_capabilities', [])],
            priority=data.get('priority', 1),
            status=TaskStatus(data.get('status', 'pending')),
            result=data.get('result'),
            error=data.get('error'),
            start_time=datetime.fromisoformat(data['start_time']) if data.get('start_time') else None,
            end_time=datetime.fromisoformat(data['end_time']) if data.get('end_time') else None,
            metadata=data.get('metadata', {})
        )

    def is_ready_to_execute(self, completed_tasks: List[str]) -> bool:
        """检查任务是否准备好执行"""
        if self.status != TaskStatus.PENDING:
            return False
        return all(dep_id in completed_tasks for dep_id in self.dependencies)

    def mark_started(self):
        """标记任务开始"""
        self.status = TaskStatus.RUNNING
        self.start_time = datetime.now()

    def mark_completed(self, result: str):
        """标记任务完成"""
        self.status = TaskStatus.COMPLETED
        self.result = result
        self.end_time = datetime.now()

    def mark_failed(self, error: str):
        """标记任务失败"""
        self.status = TaskStatus.FAILED
        self.error = error
        self.end_time = datetime.now()


@dataclass
class TaskResult:
    """任务执行结果"""
    task_id: str
    status: TaskStatus
    result: Optional[str] = None
    error: Optional[str] = None
    execution_time: Optional[float] = None  # 执行时间（秒）
    tokens_used: Optional[int] = None
    metadata: Dict[str, Any] = field(default_factory=dict)

    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            'task_id': self.task_id,
            'status': self.status.value,
            'result': self.result,
            'error': self.error,
            'execution_time': self.execution_time,
            'tokens_used': self.tokens_used,
            'metadata': self.metadata
        }


@dataclass
class QuestionAnalysis:
    """问题分析结果"""
    complexity: ComplexityLevel
    category: QuestionCategory
    suggested_approach: str
    key_topics: List[str] = field(default_factory=list)
    estimated_tasks: int = 1
    confidence: float = 0.0
    reasoning: str = ""

    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            'complexity': self.complexity.value,
            'category': self.category.value,
            'suggested_approach': self.suggested_approach,
            'key_topics': self.key_topics,
            'estimated_tasks': self.estimated_tasks,
            'confidence': self.confidence,
            'reasoning': self.reasoning
        }


@dataclass
class ExecutionSession:
    """执行会话数据模型"""
    id: str = field(default_factory=lambda: str(uuid4()))
    question_id: str = ""
    question: Optional[Question] = None
    analysis: Optional[QuestionAnalysis] = None
    tasks: List[Task] = field(default_factory=list)
    status: SessionStatus = SessionStatus.CREATED
    execution_path: ExecutionPath = ExecutionPath.DIRECT
    results: List[TaskResult] = field(default_factory=list)
    final_answer: Optional[str] = None
    created_at: datetime = field(default_factory=datetime.now)
    started_at: Optional[datetime] = None
    completed_at: Optional[datetime] = None
    total_tokens_used: int = 0
    metadata: Dict[str, Any] = field(default_factory=dict)

    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            'id': self.id,
            'question_id': self.question_id,
            'question': self.question.to_dict() if self.question else None,
            'analysis': self.analysis.to_dict() if self.analysis else None,
            'tasks': [task.to_dict() for task in self.tasks],
            'status': self.status.value,
            'execution_path': self.execution_path.value,
            'results': [result.to_dict() for result in self.results],
            'final_answer': self.final_answer,
            'created_at': self.created_at.isoformat(),
            'started_at': self.started_at.isoformat() if self.started_at else None,
            'completed_at': self.completed_at.isoformat() if self.completed_at else None,
            'total_tokens_used': self.total_tokens_used,
            'metadata': self.metadata
        }

    def get_completed_task_ids(self) -> List[str]:
        """获取已完成的任务ID列表"""
        return [task.id for task in self.tasks if task.status == TaskStatus.COMPLETED]

    def get_ready_tasks(self) -> List[Task]:
        """获取准备执行的任务"""
        completed_ids = self.get_completed_task_ids()
        return [task for task in self.tasks if task.is_ready_to_execute(completed_ids)]

    def get_task_by_id(self, task_id: str) -> Optional[Task]:
        """根据ID获取任务"""
        for task in self.tasks:
            if task.id == task_id:
                return task
        return None

    def add_task(self, task: Task):
        """添加任务"""
        self.tasks.append(task)

    def remove_task(self, task_id: str) -> bool:
        """移除任务"""
        for i, task in enumerate(self.tasks):
            if task.id == task_id:
                # 移除对此任务的依赖
                for other_task in self.tasks:
                    if task_id in other_task.dependencies:
                        other_task.dependencies.remove(task_id)
                self.tasks.pop(i)
                return True
        return False

    def update_task(self, task_id: str, updates: Dict[str, Any]) -> bool:
        """更新任务"""
        task = self.get_task_by_id(task_id)
        if not task:
            return False
        
        for key, value in updates.items():
            if hasattr(task, key):
                setattr(task, key, value)
        return True

    def is_completed(self) -> bool:
        """检查会话是否完成"""
        return self.status == SessionStatus.COMPLETED

    def get_progress(self) -> float:
        """获取执行进度（0-1）"""
        if not self.tasks:
            return 1.0 if self.final_answer else 0.0
        
        completed_count = len([task for task in self.tasks if task.status == TaskStatus.COMPLETED])
        return completed_count / len(self.tasks)


@dataclass
class ValidationResult:
    """验证结果"""
    is_valid: bool
    errors: List[str] = field(default_factory=list)
    warnings: List[str] = field(default_factory=list)

    def add_error(self, error: str):
        """添加错误"""
        self.errors.append(error)
        self.is_valid = False

    def add_warning(self, warning: str):
        """添加警告"""
        self.warnings.append(warning)


@dataclass
class ExecutionResult:
    """执行结果"""
    success: bool
    result: Optional[str] = None
    error: Optional[str] = None
    tokens_used: int = 0
    execution_time: float = 0.0
    metadata: Dict[str, Any] = field(default_factory=dict)

    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            'success': self.success,
            'result': self.result,
            'error': self.error,
            'tokens_used': self.tokens_used,
            'execution_time': self.execution_time,
            'metadata': self.metadata
        }